home *** CD-ROM | disk | FTP | other *** search
- -> FILE: ESrc:Own/applypatch.e REV: 8 --- apply BlizKick patch module to rom
- /* History
- 0 started 11th Dec 1999.
- 1 works.
- 2 12th Dec: added SPEEDROM
- 3 added HOGWAITBLIT
- 4 added test for <>$f80000 rom
- 5 no longer requires MODULES arg, now tests if any patches
- was applied.
- 6 27th Mar 2000: added elfloadseg-patch ioerr bug workaround.
- 7 12th Oct 2000: fixed small bug in SPEEDROM: the RT_END of the last
- ROMTag was made to point to $fffffe. Due some funny side effect
- ($1000000 - $fffffe) / 2 - 1 = 0) it caused the ROM's ROMTag scanner
- access longword at $fffffe, thus accessing non-existent memory.
- (maybe this was it Gunther... :-)
- 8 31st Jan 2001: Now default to 'DEVS:Modules/' dir if BKMODPATH
- env variable cannot be found. Added IGNPATH option for completeness.
- */
-
- /*
- DESCRIPTION
-
- applypatch can be used to apply BlizKick "patch" kind of modules
- to rom image. Useful if BlizKick doesn't support your system for
- some reason, but you have a working maprom tool for it. applypatch
- can also be used to speed up BlizKick booting by pre-patching rom
- image. BlizKick commandline also gets quite a bit cleaner then. ;)
-
-
- FEATURES
-
- - support for all patch modules that don't try to add resident tags
- - includes HOGWAITBLIT patch of BlizKick
- - includes SPEEDROM patch of BlizKick (kicktag reconnect)
-
-
- RESTRICTIONS
-
- - works only with 512k ROM, 256K is obsolete really
- - requires about 520k memory for patching
- - for obvious reasons there is no undo :)
-
-
- NOTES
-
- - It's a fairly good idea to keep the original ROM images somewhere
- safe
-
-
- SAMPLE RUN
-
- > applypatch DEVS:rom40068.A1200 TO T:rom40068.A1200.patched HOGWAITBLIT \
- SPEEDROM NoClick FixMath404 SpeedyIDE PatchMath020 romfixes
- reading kickfile "DEVS:rom40068.A1200"...
- rom image ok, applying patches...
- applying hogwaitblit patch...
- applying NoClick patch...
- applying FixMath404 patch...
- applying SpeedyIDE patch...
- applying PatchMath020 patch...
- Patched DiceC Mulu routine at offset $27748
- applying romfixes patch...
- applying speedrom patch...
-
- ---- total 7 patches applied ----
- calculating new checksum for image... $04E7630B
- writing patched rom image to "T:rom40068.A1200.patched"...
- done.
-
-
- TODO
-
- - add support for non-EXTRESBUF InstallModule()
- - add support for non-EXTRESBUF modules
-
-
- AUTHOR & LEGAL CRAP
-
- applypatch is written by Harry "Piru" Sintonen 1999-2001.
- applypatch is public domain.
-
- */
-
-
- OPT OSVERSION=33
-
- MODULE 'exec/memory','dos/dos','dos/var'
- MODULE 'hardware/dmabits'
-
- ENUM ARG_KICKFILE,ARG_TO,ARG_MODULE,ARG_FORCE,ARG_SPEEDROM,
- ARG_HOGWAITBLIT,ARG_IGNPATH,NUMARGS
-
- DEF progname[64]:STRING,array[NUMARGS]:ARRAY OF LONG,
- size=524288
-
- PROC main()
-
- IF KickVersion(37)=0
- WriteF('get real! this program requires kickstart 2.04+\n')
- RETURN RETURN_FAIL
- ENDIF
-
- GetProgramName(progname,63); SetStr(progname,StrLen(progname))
-
- ENDPROC main2()
-
- PROC main2()
- DEF rdargs,r
-
- r:='$VER: applypatch 1.0.4 (31.1.01)'
- FOR r:=0 TO NUMARGS-1; array[r]:=0; ENDFOR
- IF (rdargs:=ReadArgs('FROM=KICKFILE/A,TO/K/A,MODULE/M,FORCE/S,' +
- 'SPEEDROM/S,HOGWAITBLIT/S,' +
- 'IGNPATH=IGNOREBKMODPATH/S',array,NIL))
-
- r:=main3(array[ARG_KICKFILE],array[ARG_MODULE])
-
- FreeArgs(rdargs)
- ELSE
- PrintFault(IoErr(),progname)
- r:=RETURN_ERROR
- ENDIF
- ENDPROC r
-
- ENUM ROMSUMOFFS=$7FFE8,ROMSIZEOFFS=$7FFEC,ROMIDOFFS=$7FFF0,
- BLIZKICK_ID="BlzK"
-
- PROC main3(kickfile,modules:PTR TO LONG)
- DEF r,rom:PTR TO LONG,fh,sum,suc=0,err=0
- DEF modpath[256]:STRING,lock=NIL,olddir
-
- PrintF('reading kickfile "\s"...\n',kickfile)
-
- IF FileLength(kickfile)<>size
- PrintF('kickfile "\s" length not \d\n',kickfile,size)
- RETURN RETURN_ERROR
- ENDIF
-
- IF (fh:=Open(kickfile,MODE_OLDFILE))=NIL
- PrintFault(IoErr(),progname)
- PrintF('could not open kickfile "\s"\n',kickfile)
- RETURN RETURN_ERROR
- ENDIF
-
- IF (rom:=New(size))=0
- PrintFault(IoErr(),progname)
- Close(fh)
- PrintF('could not allocate \d bytes of memory\n',size)
- RETURN RETURN_ERROR
- ENDIF
-
- r:=Read(fh,rom,size); Close(fh); fh:=0
- IF r<>size
- PrintFault(IoErr(),progname)
- PrintF('error reading kickfile "\s"\n',kickfile)
- RETURN RETURN_ERROR
- ENDIF
-
- IF (Long(rom+ROMSIZEOFFS)<>size) OR
- ((rom[] AND $FFF8FFFF)<>$11104EF9)
- PrintF('bad rom image!\n')
- RETURN RETURN_ERROR
- ENDIF
-
- r:=Long(rom+4) AND $FFFF0000
- IF r<>$F80000
- PrintF('rom image not located at $00F80000, but $\h[08]!\n',r)
- RETURN RETURN_ERROR
- ENDIF
-
- IF (sum:=romresum(rom,size))<>Long(rom+ROMSUMOFFS)
- IF array[ARG_FORCE]
- PrintF('bad rom checksum $\h[08] should be $\h[08], overrided ' +
- 'by FORCE/n',
- sum,Long(rom+ROMSUMOFFS))
- ELSE
- PrintF('bad rom checksum $\h[08] should be $\h[08], can be\n' +
- 'overrided with FORCE switch\n',
- sum,Long(rom+ROMSUMOFFS))
- RETURN RETURN_ERROR
- ENDIF
- ENDIF
-
- IF Long(rom+ROMIDOFFS)=BLIZKICK_ID
- IF array[ARG_FORCE]
- PrintF('rom image has been used with BlizKick, but FORCE used\n')
- ELSE
- PrintF('rom image has been used with BlizKick before, can be\n' +
- 'overrided with FORCE switch\n')
- RETURN RETURN_ERROR
- ENDIF
- ENDIF
-
- PrintF('rom image ok, applying patches...\n')
-
- -> apply hogwaitblit if enabled
- IF array[ARG_HOGWAITBLIT]
- PrintF('\e[1mapplying hogwaitblit patch...\e[22m\n')
- IF puthogwaitblit(rom,size)
- suc++
- ELSE
- err++
- PrintF('could not patch!\n')
- ENDIF
- ENDIF
-
- IF modules
-
- IF array[ARG_IGNPATH] = 0
- -> change dir to ENV:BKMODPATH or fallback to 'DEVS:Modules/'
- IF GetVar('BKMODPATH',modpath,256,GVF_GLOBAL_ONLY) = -1
- IF GetVar('ENVARC:BKMODPATH',modpath,256,GVF_GLOBAL_ONLY) = -1
- StrCopy(modpath, 'DEVS:Modules/')
- ENDIF
- ENDIF
- IF (lock:=Lock(modpath,ACCESS_READ))
- olddir:=CurrentDir(lock)
- ENDIF
- ENDIF
-
- -> process all modules
-
- WHILE modules[]
- PrintF('\e[1mapplying \s patch...\e[22m\n',modules[]); Flush(stdout)
- IF applypatch(modules[],rom,size) THEN suc++ ELSE err++
- modules++
- ENDWHILE
-
- -> back to orig dir
-
- IF lock
- CurrentDir(olddir)
- UnLock(lock); lock:=0
- ENDIF
-
- ENDIF
-
- -> apply speedrom, if enabled
- IF array[ARG_SPEEDROM]
- PrintF('\e[1mapplying speedrom patch...\e[22m\n')
- IF speedrom(rom,size)
- suc++
- ELSE
- err++
- PrintF('could not patch!\n')
- ENDIF
- ENDIF
-
- IF err
- PrintF('\n\d patch\s failed, output file "\s" not written\n',
- err,IF err=1 THEN '' ELSE 'es',array[ARG_TO])
- ELSE
-
- IF suc=0
- PrintF('\n---- total 0 patches applied ----\ndestination file "\s" not written!\n',
- array[ARG_TO])
- ELSE
-
- PrintF('\n---- total \d patch\s applied ----\ncalculating new checksum for image...',
- suc,IF suc=1 THEN '' ELSE 'es')
-
- -> resum rom
-
- PutLong(rom+ROMSUMOFFS,sum:=romresum(rom,size))
-
- PrintF(' $\h[08]\nwriting patched rom image to "\s"...\n',sum,array[ARG_TO])
-
- -> write rom
-
- IF (fh:=Open(array[ARG_TO],MODE_NEWFILE))=NIL
- PrintFault(IoErr(),progname)
- PrintF('could not open file "\s" for writing\n',array[ARG_TO])
- RETURN RETURN_ERROR
- ENDIF
-
- r:=Write(fh,rom,size); Close(fh); fh:=0
- IF r<>size
- PrintFault(IoErr(),progname)
- DeleteFile(array[ARG_TO])
- PrintF('error writing to "\s", destination file deleted\n',array[ARG_TO])
- RETURN RETURN_ERROR
- ENDIF
- ENDIF
-
- ENDIF
-
- PrintF('done.\n')
-
- ENDPROC
-
- PROC puthogwaitblit(rom,size)
-
- MOVEM.L D1-D7/A0-A6,-(A7)
-
- MOVE.L rom,A0
- MOVE.L size,D0
-
- MOVEQ #0,D7
-
- CMP.W #39,$C(A0) -> Requires rom 39+
- BCS.B phwb_exit
-
- LEA -4(A0,D0.L),A1
-
- MOVE.L #$08390006,D0
- phwb_find:
- ADDQ.L #2,A0
- CMPA.L A1,A0
- BEQ.B phwb_exit
- CMP.L (A0),D0
- BNE.B phwb_find
- CMP.L #$00DFF002,4(A0)
- BNE.B phwb_find
- CMP.L #$66024E75,8(A0)
- BNE.B phwb_find
-
- CMP.L #$08390006,-8(A0) -> No KS 1.x!
- BEQ.B phwb_exit
- CMP.L #$4A3900DF,-6(A0) -> KS 2.x/3.x:
- BNE.B phwb_exit
- SUBQ.L #6,A0
- LEA phwb_waitblit(PC),A1
- MOVEQ #21,D0 -> 42/2
- phwb_copy:
- MOVE.W (A1)+,(A0)+
- SUBQ.L #1,D0
- BNE.B phwb_copy
- MOVEQ #1,D7
-
- phwb_exit:
- MOVE.L D7,D0
- MOVEM.L (A7)+,D1-D7/A0-A6
- RETURN D0
-
- -> 3.0 48 bytes
- -> 3.1 48 bytes
- phwb_waitblit:
- BTST #6,$DFF002 -> 8 DMAB_BLTDONE=14 dmaconr
- BNE.B phwb_wb_gowait -> 2
- RTS -> 2
- phwb_wb_gowait:
- MOVE.L A0,-(A7) -> 2
- LEA $DFF002,A0 -> 6 dmaconr
- MOVE.W #$8400,148(A0) -> 6 DMAF_SETCLR OR DMAF_BLITHOG dmacon-dmaconr
- phwb_wb_wait:
- BTST #6,(A0) -> 4 DMAB_BLTDONE=14 DMAB_BLTDONE-8
- BNE.B phwb_wb_wait -> 2
- MOVE.W #$0400,148(A0) -> 6 DMAF_BLITHOG dmacon-dmaconr
- MOVE.L (A7)+,A0 -> 2
- RTS -> 2 =42
-
- ENDPROC
-
- PROC speedrom(rom,size)
-
- -> Reconnect resident modules:
-
- MOVEM.L D1-D7/A0-A6,-(A7)
-
- MOVE.L rom,A0
- MOVE.L size,D0
-
- MOVE.L #$01000000,D2
- SUB.L D0,D2
- MOVE.L A0,A5
- SUB.L D2,A5 -> a5=difference
-
- MOVEQ #-28,D1 -> -(RT_SIZE+2),D1
- ADD.L D0,D1
- SUB.L A1,A1
- sr_find:
- SUBQ.L #2,D1
- BLS.B sr_done
- CMP.W #$4AFC,(A0)+ -> RTC_MATCHWORD,(A0)+
- BNE.B sr_find
- MOVEQ #2,D0
- ADD.L (A0),D0 -> RT_MATCHTAG-2(A0),D0
- ADD.L A5,D0
- CMP.L A0,D0
- BNE.B sr_find
- SUBQ.L #2,A0
- MOVE.L A1,D0
- BEQ.B sr_is_1st
- MOVE.L A0,D0
- SUB.L A5,D0
- MOVE.L D0,6(A1) -> RT_ENDSKIP(A1)
- sr_is_1st:
- MOVE.L A0,A1
- LEA 26(A0),A0 ->RT_SIZE(A0),A0
- BRA.B sr_find
- sr_done:
- MOVE.L A1,D0
- BEQ.B sr_none
- -> make last RT_ENDSKIP point $00FFFFFA
- MOVE.L #$00FFFFFA,6(A1)
- sr_none:
- MOVEQ #1,D7
-
- MOVE.L D7,D0
- MOVEM.L (A7)+,D1-D7/A0-A6
- ENDPROC D0
-
- ENUM BKMODULE_ID=$707A4E75,BKEP_ID=$4E71
-
- PROC applypatch(patch,rom,size)
- DEF ret=0,seg,module:PTR TO LONG
-
- IF (seg:=Lock(patch,ACCESS_READ))
- UnLock(seg)
-
- IF (seg:=LoadSeg(patch))
-
- module:=Shl(seg,2)+4
-
- IF module[]=BKMODULE_ID
- IF module[1]=BKEP_ID
-
- MOVEM.L D1-D7/A0-A6,-(A7)
- LEA findresident(PC),A2
- LEA installmodule(PC),A3
- MOVE.L dosbase,D6
- MOVE.L execbase,A6
- MOVE.L rom,A0
- LEA $F80000,A1
- MOVE.L #$80000,D0
- MOVE.L module,A5
- LEA printf(PC),A4
- JSR 8(A5)
- MOVEM.L (A7)+,D1-D7/A0-A6
- MOVE.L D0,ret
-
- IF ret=0
- PrintF('failed, module returned error\n')
- ENDIF
-
- ELSE
- PrintF('failed, only patch modules supported!\n')
- ENDIF
- ELSE
- PrintF('failed, not a blizkick module!\n')
- ENDIF
-
- UnLoadSeg(seg)
- ELSE
- PrintFault(IoErr(),progname)
- PrintF('failed, could not load module!\n')
- ENDIF
- ELSE
- PrintFault(IoErr(),progname)
- PrintF('failed, could not load module!\n')
- ENDIF
- RETURN ret
-
-
- -> IN: a0=ptr to ROM, d0=rom len, a1=ptr to resident name
- -> OUT: d0=ptr to resident (buf) or NULL
- findresident:
- MOVEM.L D1-D7/A0-A6,-(A7)
- MOVEQ #1,D6
- MOVE.L A1,A3
- MOVE.L #$01000000,D2
- SUB.L D0,D2 -> d2=rom start (rom)
- MOVE.L A0,A5
- SUB.L D2,A5 -> A5=diff
- MOVEQ #26-2,D1 ->RT_SIZE-2,D1
- SUB.L D1,D0
- MOVE.W #$4AFC,D1 ->RTC_MATCHWORD,D1
- fr_find:
- SUBQ.L #2,D0
- BLS.B fr_exit_nf
- CMP.W (A0)+,D1
- BNE.B fr_find
- MOVEQ #2,D2
- ADD.L (A0),D2 ->RT_MATCHTAG-2(A0),D2
- ADD.L A5,D2
- CMP.L A0,D2
- BNE.B fr_find
- MOVE.L 12(A0),A1 ->RT_NAME-2(A0),A1
- ADD.L A5,A1
- MOVE.L A3,A2
- fr_compare:
- CMPM.B (A2)+,(A1)+
- BNE.B fr_find
- TST.B -1(A2)
- BNE.B fr_compare
-
- MOVE.L A0,D0
- SUBQ.L #2,D0
-
- fr_exit2:
- MOVEM.L (A7)+,D1-D7/A0-A6
- RTS
-
- fr_exit_nf:
- MOVEQ #0,D0
- BRA.B fr_exit2
-
-
- -> IN: a0=ptr to ROM, d0=rom len, a1=ptr to module, d6=dosbase
- -> OUT: d0=success
- installmodule:
- MOVEQ #0,D0
- RTS
-
- -> IN: a0=FmtString, a1=Array (may be 0), d6=dosbase
- printf:
- EXG D6,A6
- MOVEM.L D0-D2/A0-A1,-(A7)
- MOVE.L A0,D1
- MOVE.L A1,D2
- JSR -$3BA(A6) -> _LVOVPrintF
- MOVEM.L (A7)+,D0-D2/A0-A1
- EXG D6,A6
- RTS
-
- ENDPROC
-
-
- PROC romresum(rom,size)
- MOVE.L rom,A0
- MOVE.L size,D0
- MOVE.L D0,D1
- LSR.L #2,D1
- MOVE.L -$18(A0,D0.L),D0
- NOT.L D0
- rr_loop:
- ADD.L (A0)+,D0
- BCC.B rr_skip
- ADDQ.L #1,D0
- rr_skip:
- SUBQ.L #1,D1
- BNE.B rr_loop
- NOT.L D0
- ENDPROC D0
-